﻿using KingApp.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml;
using System.Xml.Linq;

namespace KingApp.DAL
{
    public class XmlHelper
    {
        private static IEnumerable<XElement> missingItems = new List<XElement>();
        private static string latestIssue = string.Empty;
        private static string url = @"http://adkjh.cailele.com/cq11x5/xqch_chzs.aspx";
        private static string param = "?days=";

        public static int LoopCount = 0;

        private static string GetXmlFile()
        {
            return string.Concat(Directory.GetCurrentDirectory(), @"\data\data.xml");
        }

        public static IEnumerable<XElement> GetXmlItems()
        {
            return LoadXmlFile().Root.Descendants("item");
        }

        public static XDocument LoadXmlFile()
        {
            return XDocument.Load(GetXmlFile());
        }


        public static void GetLatestIssue()
        {
            latestIssue = LoadXmlFile().Root.Elements("item").FirstOrDefault().Attribute("issue").Value;
        }

        public static void UpdateLotteryData(int days)
        {

            //XDocument doc = LoadXmlFile();
            //var em = doc.Root.Elements("item");
            //em.Remove();
            //doc.Save(GetXmlFile());

            string response = string.Empty;
            var iLoop = 0;

            for (int i = days; i >= 0; i--)
            {
                while (string.IsNullOrEmpty(response) && iLoop < 100)
                {
                    response = HttpHelper.Get(url, param + i.ToString(), null);
                    iLoop++;
                    Thread.Sleep(300);
                }

                if (null != response)
                {
                    var result = response.Split('|');
                    Regex reg = new Regex(@"(?is)<table[^>]*>(.*?)</table>");
                    var xml = result[result.Length - 1].Replace("<br/>", ",");
                    MatchCollection mc = reg.Matches(xml);

                    foreach (Match m in mc)
                    {
                        xml = m.Groups[1].Value;
                    }
                    var date = DateTime.Now.Subtract(new TimeSpan(i, 0, 0, 0));
                    var file = XmlHelper.GetHistoryFile(date);
                    XDocument doc = XDocument.Load(file);
                    var em = doc.Root.Elements("item");
                    em.Remove();
                    doc.Save(file);
                    AddItems(doc, xml, file);
                    response = string.Empty;
                    iLoop = 0;
                }

                LoopCount = days - i;
            }
        }

        public static void GetMissingItems(string xml, out bool findFlag)
        {
            var items = GetItems(xml);
            var isExist = items.Where(i => i.Elements("li").Where(li => li.Value == latestIssue).FirstOrDefault() != null).FirstOrDefault();
            missingItems = missingItems.Concat(items);

            findFlag = isExist != null;
        }

        public static void AddMissingItems()
        {
            XDocument doc = LoadXmlFile();

            var response = string.Empty;
            var iLoop = 0;
            for (var i = 1; i < 100; i++)
            {
                while (string.IsNullOrEmpty(response) && iLoop < 100)
                {
                    response = HttpHelper.Get(url, param + i.ToString(), null);
                    Thread.Sleep(200);
                    iLoop++;
                }

                var result = response.Split('|');
                var xml = result[result.Length - 1].Replace("<br/>", ",");
                bool findFlag;

                GetMissingItems(xml, out findFlag);
                response = string.Empty;
                iLoop = 0;

                if (findFlag)
                {
                    break;
                }
            }

            missingItems = missingItems.Reverse();

            missingItems.Select(i =>
                {
                    var li = i.Elements("li").Select(l => new { value = l.Value }).ToList();
                    var issue = li[0].value;
                    var lottery = li[1].value.Replace("-", string.Empty);
                    var sum = li[2].value;
                    var isExist = doc.Root.Elements("item").Where(e => e.Attribute("issue").Value == issue).FirstOrDefault();
                    if (isExist == null)
                    {
                        doc.Root.AddFirst(CreateItem(issue, lottery, sum));
                    }

                    return i;
                }).ToList();

            doc.Save(GetXmlFile());
        }

        public static void AddItems(XDocument doc, string xml, string file)
        {
            var items = GetItems(xml);
            items = items.Reverse();
            foreach (var item in items)
            {
                var td = item.Elements("td").Take(7).Select(l => new { value = l.Value }).ToList();
                var issue = td[0].value;
                var time = td[1].value;
                var lottery = string.Concat(td[2].value, ",", td[3].value, ",", td[4].value, ",", td[5].value, ",", td[6].value);
                var sum = "0";
                doc.Root.AddFirst(CreateItem(issue, lottery, sum, time));
            }

            doc.Save(file);
        }

        public static void AddOneItem(out bool isAdded)
        {
            isAdded = false;
            string response = string.Empty;
            int iLoop = 0;

            while (string.IsNullOrEmpty(response) && iLoop < 100)
            {
                response = HttpHelper.Get(url, param + "1", null);
                Thread.Sleep(300);
                iLoop++;
            }

            if (null != response)
            {
                var result = response.Split('|');

                if (result == null || result.Length < 2)
                {
                    return;
                }

                XDocument doc = LoadXmlFile();

                Regex reg = new Regex(@"(?is)<table[^>]*>(.*?)</table>");
                var xml = result[result.Length - 1].Replace("<br/>", ",");
                MatchCollection mc = reg.Matches(xml);

                var items = GetItems(xml).FirstOrDefault().Elements("li").Select(l => new { value = l.Value }).ToList();
                var issue = items[0].value;
                var lottery = items[1].value.Replace("-", string.Empty);
                var sum = items[2].value;
                var isExist = doc.Root.Elements("item").Where(i => i.Attribute("issue").Value == issue).FirstOrDefault();
                if (isExist == null)
                {
                    InsertLottery(doc, issue, lottery, sum);
                    isAdded = true;
                }
            }
        }

        public static IEnumerable<XElement> GetItems(string xml)
        {
            xml = string.Concat("<items>", xml.Replace("&nbsp;", string.Empty), "</items>");
            XElement root = XElement.Parse(xml);
            return root.Elements("tr").Where(r => r.Attribute("title") == null && r.Elements("td").First().Attribute("class").Value == "yellow bold");
        }

        public static XElement GetItem(IEnumerable<XElement> items)
        {
            return items.FirstOrDefault();
        }

        public static void InsertLottery(XDocument doc, string issue, string lottery, string sum)
        {
            XElement item = CreateItem(issue, lottery, sum);
            doc.Root.AddFirst(item);
            doc.Save(GetXmlFile());
        }

        public static XElement CreateItem(string issue, string lottery, string sum, string time = null)
        {
            return new XElement("item",
                new XAttribute("issue", issue),
                new XAttribute("lottery", lottery),
                new XAttribute("sum", sum),
                new XAttribute("time", time ?? DateTime.Now.ToString())
                );

        }

        public static string GetHistoryFile(DateTime date)
        {
            string path = Path.Combine(Environment.CurrentDirectory, @"Historic\", date.Year.ToString("0000"), date.Month.ToString("00"));
            XmlHelper.CreateDirectory(path);

            string file = path + "\\" + date.Year.ToString("0000") + date.Month.ToString("00") + date.Day.ToString("00") + ".xml";
            XmlHelper.CreateFile(file);
            return file;
        }


        public static void CreateDirectory(string dirPath)
        {
            string[] paths = dirPath.Split('\\');
            string path = paths[0];
            for (int i = 1; i < paths.Length; i++)
            {
                path = path + "\\" + paths[i];
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
            }
        }

        public static void CreateFile(string path)
        {
            if (!File.Exists(path))
            {
                XmlDocument xmlDoc = new XmlDocument();
                XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
                XmlElement rootNode = xmlDoc.CreateElement("items");
                xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
                xmlDoc.AppendChild(rootNode);

                xmlDoc.Save(path);
            }
        }


        public static string GetUserInfoXmlFile()
        {
            return Path.Combine(Environment.CurrentDirectory, @"Resource\userinfo.xml");
        }

        public static IEnumerable<XElement> GetUserInfoItems()
        {
            return XDocument.Load(GetUserInfoXmlFile()).Root.Descendants("user");
        }

        public static void UpdateUserInfo(string sn)
        {
            XDocument doc = XDocument.Load(GetUserInfoXmlFile());
            var em = doc.Root.Elements("user");
            em.Remove();
            doc.Save(GetUserInfoXmlFile());

            if (null != sn)
            {
                //doc.Root.AddFirst(new XElement("user", new XAttribute("username", SSCAI.Common.CalculateHelper.GetUserName(sn)), new XAttribute("sn", sn)));
                // doc.Save(GetUserInfoXmlFile());
            }
        }
    }
}
